<?php

declare(strict_types=1);

namespace App\Services;

use App\Services\Database;
use App\Core\Config;

final class BackupService
{
    public static function createDatabaseBackup(): array
    {
        $result = [
            'success' => false,
            'message' => '',
            'filename' => '',
            'size' => 0
        ];

        try {
            $db = Database::pdo();
            $dbName = Config::get('DB_NAME');
            $timestamp = date('Y-m-d_H-i-s');
            $filename = "backup_{$dbName}_{$timestamp}.sql";
            $backupPath = APP_ROOT . "/storage/backups";

            // 创建备份目录
            if (!is_dir($backupPath)) {
                mkdir($backupPath, 0755, true);
            }

            $fullPath = $backupPath . '/' . $filename;
            $backup = fopen($fullPath, 'w');

            if (!$backup) {
                throw new \Exception('无法创建备份文件');
            }

            // 写入备份头信息
            fwrite($backup, "-- MyCMS Database Backup\n");
            fwrite($backup, "-- Generated on: " . date('Y-m-d H:i:s') . "\n");
            fwrite($backup, "-- Database: {$dbName}\n\n");
            fwrite($backup, "SET FOREIGN_KEY_CHECKS=0;\n\n");

            // 获取所有表
            $tables = $db->query("SHOW TABLES")->fetchAll(\PDO::FETCH_COLUMN);

            foreach ($tables as $table) {
                // 获取表结构
                fwrite($backup, "-- Table structure for `{$table}`\n");
                fwrite($backup, "DROP TABLE IF EXISTS `{$table}`;\n");

                $createTable = $db->query("SHOW CREATE TABLE `{$table}`")->fetch(\PDO::FETCH_ASSOC);
                fwrite($backup, $createTable['Create Table'] . ";\n\n");

                // 获取表数据
                $rows = $db->query("SELECT * FROM `{$table}`")->fetchAll(\PDO::FETCH_ASSOC);

                if (!empty($rows)) {
                    fwrite($backup, "-- Data for table `{$table}`\n");

                    foreach ($rows as $row) {
                        $values = array_map(function ($value) use ($db) {
                            return $value === null ? 'NULL' : $db->quote($value);
                        }, array_values($row));

                        $columns = '`' . implode('`, `', array_keys($row)) . '`';
                        $valuesStr = implode(', ', $values);

                        fwrite($backup, "INSERT INTO `{$table}` ({$columns}) VALUES ({$valuesStr});\n");
                    }
                    fwrite($backup, "\n");
                }
            }

            fwrite($backup, "SET FOREIGN_KEY_CHECKS=1;\n");
            fclose($backup);

            $result['success'] = true;
            $result['message'] = '数据库备份创建成功';
            $result['filename'] = $filename;
            $result['size'] = filesize($fullPath);
        } catch (\Throwable $e) {
            $result['message'] = '备份失败: ' . $e->getMessage();
            error_log("Backup error: " . $e->getMessage());
        }

        return $result;
    }

    public static function getBackupList(): array
    {
        $backups = [];
        $backupPath = APP_ROOT . "/storage/backups";

        if (!is_dir($backupPath)) {
            return $backups;
        }

        $files = glob($backupPath . '/backup_*.sql');

        foreach ($files as $file) {
            $backups[] = [
                'filename' => basename($file),
                'size' => filesize($file),
                'created_at' => date('Y-m-d H:i:s', filemtime($file)),
                'path' => $file
            ];
        }

        // 按创建时间倒序排列
        usort($backups, function ($a, $b) {
            return filemtime($b['path']) - filemtime($a['path']);
        });

        return $backups;
    }

    public static function deleteBackup(string $filename): bool
    {
        $backupPath = APP_ROOT . "/storage/backups/" . basename($filename);

        if (file_exists($backupPath) && strpos(basename($filename), 'backup_') === 0) {
            return unlink($backupPath);
        }

        return false;
    }

    public static function downloadBackup(string $filename): void
    {
        $backupPath = APP_ROOT . "/storage/backups/" . basename($filename);

        if (file_exists($backupPath) && strpos(basename($filename), 'backup_') === 0) {
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
            header('Content-Length: ' . filesize($backupPath));
            readfile($backupPath);
            exit;
        }

        http_response_code(404);
        echo '备份文件不存在';
        exit;
    }
}
